<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="WrorT" id="WrorT"><span data-lake-id="ua9cec344" id="ua9cec344">典型回答</span></h1>
  <p data-lake-id="u148ac847" id="u148ac847"><strong><span data-lake-id="uf36502d1" id="uf36502d1">线程安全：</span></strong></p>
  <p data-lake-id="u95a88c0d" id="u95a88c0d"><strong><span data-lake-id="u201696e6" id="u201696e6">​</span></strong><br></p>
  <p data-lake-id="u0484f456" id="u0484f456"><span data-lake-id="u9df4c178" id="u9df4c178">HashMap是非线程安全的。</span></p>
  <p data-lake-id="u7382741b" id="u7382741b"><span data-lake-id="u83311b25" id="u83311b25">Hashtable 中的方法是同步的，所以它是线程安全的。</span></p>
  <p data-lake-id="u87d0877d" id="u87d0877d"><span data-lake-id="u1644a813" id="u1644a813">ConcurrentHashMap在JDK 1.8之前使用分段锁保证线程安全， ConcurrentHashMap默认情况下将hash表分为16个桶（分片），在加锁的时候，针对每个单独的分片进行加锁，其他分片不受影响。锁的粒度更细，所以他的性能更好。</span></p>
  <p data-lake-id="u2023914b" id="u2023914b"><span data-lake-id="u76c19949" id="u76c19949">ConcurrentHashMap在JDK 1.8中，采用了一种新的方式来实现线程安全，即使用了CAS+synchronized，这个实现被称为"分段锁"的变种，也被称为"锁分离"，它将锁定粒度更细，把锁的粒度从整个Map降低到了单个桶。</span></p>
  <p data-lake-id="u9ca8fbf1" id="u9ca8fbf1"><span data-lake-id="ue64c92d1" id="ue64c92d1">​</span><br></p>
  <p data-lake-id="u59878438" id="u59878438"><strong><span data-lake-id="ucc045741" id="ucc045741">继承关系：</span></strong></p>
  <p data-lake-id="u4c1e74ad" id="u4c1e74ad"><span data-lake-id="ue410c638" id="ue410c638">HashTable是基于陈旧的Dictionary类继承来的。</span></p>
  <p data-lake-id="u0594dc09" id="u0594dc09"><span data-lake-id="u341c37e1" id="u341c37e1">HashMap继承的抽象类AbstractMap实现了Map接口。</span></p>
  <p data-lake-id="uc29fb32f" id="uc29fb32f"><span data-lake-id="u39505074" id="u39505074">ConcurrentHashMap同样继承了抽象类AbstractMap，并且实现了ConcurrentMap&#x0;接口。</span></p>
  <p data-lake-id="ua1804a47" id="ua1804a47"><span data-lake-id="u5096e580" id="u5096e580">​</span><br></p>
  <p data-lake-id="u038514f9" id="u038514f9"><strong><span data-lake-id="u911b4381" id="u911b4381">允不允许null值：</span></strong></p>
  <p data-lake-id="ube7c6ee9" id="ube7c6ee9"><span data-lake-id="u5c23fb20" id="u5c23fb20">HashTable中，key和value都不允许出现null值，否则会抛出NullPointerException异常。 </span></p>
  <p data-lake-id="u54dae5ff" id="u54dae5ff"><span data-lake-id="udc8ded62" id="udc8ded62">HashMap中，null可以作为键或者值都可以。</span></p>
  <p data-lake-id="u7cc62a93" id="u7cc62a93"><span data-lake-id="ua8e099f1" id="ua8e099f1">ConcurrentHashMap中，key和value都不允许为null。</span></p>
  <p data-lake-id="u510caf42" id="u510caf42"><span data-lake-id="ue0c3a1d3" id="ue0c3a1d3">​</span><br></p>
  <p data-lake-id="u794a9975" id="u794a9975"><span data-lake-id="u94d54ac6" id="u94d54ac6">​</span><br></p>
  <p data-lake-id="u9fc290fe" id="u9fc290fe"><strong><span data-lake-id="uf624cac3" id="uf624cac3">默认初始容量和扩容机制：</span></strong></p>
  <p data-lake-id="u309236fc" id="u309236fc"><span data-lake-id="u8a8e2995" id="u8a8e2995" class="lake-fontsize-12" style="color: rgb(55, 65, 81); background-color: rgb(247, 247, 248)">​</span><br></p>
  <p data-lake-id="u30cedfa1" id="u30cedfa1"><span data-lake-id="udb1d5c05" id="udb1d5c05">HashMap的默认初始容量为16，默认的加载因子为0.75，即当HashMap中元素个数超过容量的75%时，会进行扩容操作。扩容时，容量会扩大为原来的两倍，并将原来的元素重新分配到新的桶中。</span></p>
  <p data-lake-id="u3cb636b6" id="u3cb636b6"><span data-lake-id="ueb9a958b" id="ueb9a958b">​</span><br></p>
  <p data-lake-id="u70bd4a8b" id="u70bd4a8b"><span data-lake-id="u3df2aa94" id="u3df2aa94">Hashtable，默认初始容量为11，默认的加载因子为0.75，即当Hashtable中元素个数超过容量的75%时，会进行扩容操作。扩容时，容量会扩大为原来的两倍加1，并将原来的元素重新分配到新的桶中。</span></p>
  <p data-lake-id="udd62d54b" id="udd62d54b"><span data-lake-id="ub8cf4dc3" id="ub8cf4dc3">​</span><br></p>
  <p data-lake-id="u89f87bdd" id="u89f87bdd"><span data-lake-id="ue105a282" id="ue105a282">ConcurrentHashMap，默认初始容量为16，默认的加载因子为0.75，即当ConcurrentHashMap中元素个数超过容量的75%时，会进行扩容操作。扩容时，容量会扩大为原来的两倍，并会采用分段锁机制，将ConcurrentHashMap分为多个段(segment)，每个段独立进行扩容操作，避免了整个ConcurrentHashMap的锁竞争。</span></p>
  <p data-lake-id="u4d78e07f" id="u4d78e07f"><span data-lake-id="u1cd21fee" id="u1cd21fee"> </span></p>
  <p data-lake-id="u489d6ee0" id="u489d6ee0"><span data-lake-id="u02924caa" id="u02924caa">​</span><br></p>
  <p data-lake-id="u172dae9e" id="u172dae9e"><strong><span data-lake-id="uf93643d0" id="uf93643d0">遍历方式的内部实现上不同 ：</span></strong></p>
  <p data-lake-id="ud3c8d404" id="ud3c8d404"><span data-lake-id="u2d2ab83f" id="u2d2ab83f">​</span><br></p>
  <p data-lake-id="u1da6ff27" id="u1da6ff27"><span data-lake-id="u83aec76e" id="u83aec76e">HashMap使用EntrySet进行遍历，即先获取到HashMap中所有的键值对(Entry)，然后遍历Entry集合。支持fail-fast，也就是说在遍历过程中，若HashMap的结构被修改（添加或删除元素），则会抛出ConcurrentModificationException。如果只需要遍历HashMap中的key或value，可以使用KeySet或Values来遍历。</span></p>
  <p data-lake-id="u03092979" id="u03092979"><span data-lake-id="u3f882b47" id="u3f882b47">​</span><br></p>
  <p data-lake-id="ub11ebade" id="ub11ebade"><span data-lake-id="u042eb8ba" id="u042eb8ba">Hashtable使用Enumeration进行遍历，即获取Hashtable中所有的key，然后遍历key集合。遍历过程中，Hashtable的结构发生变化时，Enumeration会失效。</span></p>
  <p data-lake-id="u2d97e31e" id="u2d97e31e"><span data-lake-id="uc19b7664" id="uc19b7664">​</span><br></p>
  <p data-lake-id="uef33bf63" id="uef33bf63"><span data-lake-id="u187c375d" id="u187c375d">ConcurrentHashMap使用分段锁机制，因此在遍历时需要注意，遍历时ConcurrentHashMap的某个段被修改不会影响其他段的遍历。可以使用EntrySet、KeySet或Values来遍历ConcurrentHashMap，其中EntrySet遍历时效率最高。遍历过程中，ConcurrentHashMap的结构发生变化时，不会抛出ConcurrentModificationException异常，但是在遍历时可能会出现数据不一致的情况，因为遍历器仅提供了弱一致性保障。</span></p>
  <p data-lake-id="u8649181d" id="u8649181d"><span data-lake-id="ud53dfd2a" id="ud53dfd2a">​</span><br></p>
  <p data-lake-id="uc74ce2e2" id="uc74ce2e2"><span data-lake-id="u6458ff0c" id="u6458ff0c">​</span><br></p>
  <table data-lake-id="EdgdU" id="EdgdU" margin="true" width-mode="contain" class="lake-table" style="width: 1000px">
   <colgroup>
    <col width="250">
    <col width="250">
    <col width="250">
    <col width="250">
   </colgroup>
   <tbody>
    <tr data-lake-id="uc0699715" id="uc0699715">
     <td data-lake-id="u7654ba63" id="u7654ba63">
      <p data-lake-id="u814a6954" id="u814a6954"><span data-lake-id="u06a58e82" id="u06a58e82">特性/集合类</span></p></td>
     <td data-lake-id="u553bb3e3" id="u553bb3e3">
      <p data-lake-id="u307d5541" id="u307d5541"><span data-lake-id="u127ed2ad" id="u127ed2ad">HashMap</span></p></td>
     <td data-lake-id="uf71f6797" id="uf71f6797">
      <p data-lake-id="u04076b1f" id="u04076b1f"><span data-lake-id="u7805ad27" id="u7805ad27">Hashtable</span></p></td>
     <td data-lake-id="uf00b0407" id="uf00b0407">
      <p data-lake-id="u9bcad950" id="u9bcad950"><span data-lake-id="u91d78eb4" id="u91d78eb4">ConcurrentHashMap</span></p></td>
    </tr>
    <tr data-lake-id="ua073a5e9" id="ua073a5e9">
     <td data-lake-id="ub3bc0312" id="ub3bc0312">
      <p data-lake-id="ud94684c4" id="ud94684c4"><span data-lake-id="u0aecb75e" id="u0aecb75e">线程安全</span></p></td>
     <td data-lake-id="u4cc2f291" id="u4cc2f291">
      <p data-lake-id="ube2b7a56" id="ube2b7a56"><span data-lake-id="uc185a2ea" id="uc185a2ea">否</span></p></td>
     <td data-lake-id="uf2b913d0" id="uf2b913d0">
      <p data-lake-id="ucf00c42a" id="ucf00c42a"><span data-lake-id="uf10f401b" id="uf10f401b">是，基于方法锁</span></p></td>
     <td data-lake-id="u1758ecba" id="u1758ecba">
      <p data-lake-id="udace8aad" id="udace8aad"><span data-lake-id="u17933cbd" id="u17933cbd">是，基于分段锁</span></p></td>
    </tr>
    <tr data-lake-id="u73e6b85f" id="u73e6b85f">
     <td data-lake-id="uabf92b2e" id="uabf92b2e">
      <p data-lake-id="u25740d3b" id="u25740d3b"><span data-lake-id="u2af14210" id="u2af14210">继承关系</span></p></td>
     <td data-lake-id="u8f0ec034" id="u8f0ec034">
      <p data-lake-id="uf25ece50" id="uf25ece50"><span data-lake-id="u072ef379" id="u072ef379">AbstractMap</span></p></td>
     <td data-lake-id="uaa01a592" id="uaa01a592">
      <p data-lake-id="u55fc2b2a" id="u55fc2b2a"><span data-lake-id="u293a20bf" id="u293a20bf">Dictionary</span></p></td>
     <td data-lake-id="u6639b81c" id="u6639b81c">
      <p data-lake-id="uf88a14fd" id="uf88a14fd"><span data-lake-id="u8430b806" id="u8430b806">AbstractMap，ConcurrentMap</span></p></td>
    </tr>
    <tr data-lake-id="ub5b0e8ed" id="ub5b0e8ed">
     <td data-lake-id="u02863b46" id="u02863b46">
      <p data-lake-id="u23066b08" id="u23066b08"><span data-lake-id="u7023f493" id="u7023f493">允许null值</span></p></td>
     <td data-lake-id="uf07fc154" id="uf07fc154">
      <p data-lake-id="u17ac16cf" id="u17ac16cf"><span data-lake-id="u2d0f0812" id="u2d0f0812">K-V都允许</span></p></td>
     <td data-lake-id="u0d91da1a" id="u0d91da1a">
      <p data-lake-id="u680c63ae" id="u680c63ae"><span data-lake-id="ue0d471b0" id="ue0d471b0">K-V都不允许</span></p></td>
     <td data-lake-id="ua5ad4bc8" id="ua5ad4bc8">
      <p data-lake-id="ue8291557" id="ue8291557"><span data-lake-id="u15fac0c7" id="u15fac0c7">K-V都不允许</span></p></td>
    </tr>
    <tr data-lake-id="u0538d71d" id="u0538d71d">
     <td data-lake-id="u6b07498b" id="u6b07498b">
      <p data-lake-id="ufb36a42c" id="ufb36a42c"><span data-lake-id="ud51d147d" id="ud51d147d">默认初始容量</span></p></td>
     <td data-lake-id="u16a73fcd" id="u16a73fcd">
      <p data-lake-id="u3e70d812" id="u3e70d812"><span data-lake-id="u2d5f68ae" id="u2d5f68ae">16</span></p></td>
     <td data-lake-id="uc8d1f840" id="uc8d1f840">
      <p data-lake-id="u0b047e72" id="u0b047e72"><span data-lake-id="u84b5271c" id="u84b5271c">11</span></p></td>
     <td data-lake-id="u7e22d7b9" id="u7e22d7b9">
      <p data-lake-id="u9d312f08" id="u9d312f08"><span data-lake-id="u6586d69d" id="u6586d69d">16</span></p></td>
    </tr>
    <tr data-lake-id="u93e13bcd" id="u93e13bcd">
     <td data-lake-id="u5caf3cb4" id="u5caf3cb4">
      <p data-lake-id="ud04d14ed" id="ud04d14ed"><span data-lake-id="u40abe12b" id="u40abe12b">默认加载因子</span></p></td>
     <td data-lake-id="u4a48c294" id="u4a48c294">
      <p data-lake-id="u020de812" id="u020de812"><span data-lake-id="u332c4d1f" id="u332c4d1f">0.75</span></p></td>
     <td data-lake-id="u83e03681" id="u83e03681">
      <p data-lake-id="u58ea8cdf" id="u58ea8cdf"><span data-lake-id="ua587a9a8" id="ua587a9a8">0.75</span></p></td>
     <td data-lake-id="uf21f6303" id="uf21f6303">
      <p data-lake-id="u80934919" id="u80934919"><span data-lake-id="u459f47b3" id="u459f47b3">0.75</span></p></td>
    </tr>
    <tr data-lake-id="ufd26ca04" id="ufd26ca04">
     <td data-lake-id="u1ba78bd1" id="u1ba78bd1">
      <p data-lake-id="uea1b2294" id="uea1b2294"><span data-lake-id="u17cba065" id="u17cba065">扩容后容量</span></p></td>
     <td data-lake-id="u78ede2cb" id="u78ede2cb">
      <p data-lake-id="u4a24b2cf" id="u4a24b2cf"><span data-lake-id="u56b35d02" id="u56b35d02">原来的两倍</span></p></td>
     <td data-lake-id="u1a064012" id="u1a064012">
      <p data-lake-id="u9241afc6" id="u9241afc6"><span data-lake-id="u1fccf39d" id="u1fccf39d">原来的两倍加1</span></p></td>
     <td data-lake-id="udf9fbb08" id="udf9fbb08">
      <p data-lake-id="u255b3100" id="u255b3100"><span data-lake-id="u00dc00c7" id="u00dc00c7">原来的两倍</span></p></td>
    </tr>
    <tr data-lake-id="u2f10e958" id="u2f10e958">
     <td data-lake-id="uec7da8f2" id="uec7da8f2">
      <p data-lake-id="u6fc18bae" id="u6fc18bae"><span data-lake-id="u5a5ee2b7" id="u5a5ee2b7">是否支持fail-fast</span></p></td>
     <td data-lake-id="u042b3789" id="u042b3789">
      <p data-lake-id="u0422b32f" id="u0422b32f"><span data-lake-id="u33dae729" id="u33dae729">支持</span></p></td>
     <td data-lake-id="u29e766af" id="u29e766af">
      <p data-lake-id="uac14ec34" id="uac14ec34"><span data-lake-id="u54b9cd25" id="u54b9cd25">不支持</span></p></td>
     <td data-lake-id="uc703f98e" id="uc703f98e">
      <p data-lake-id="u56555734" id="u56555734"><span data-lake-id="u54b5cb70" id="u54b5cb70">fail-safe</span></p></td>
    </tr>
   </tbody>
  </table>
  <p data-lake-id="u2cc102b1" id="u2cc102b1"><br></p>
  <p data-lake-id="u12f5cca2" id="u12f5cca2"><br></p>
  <p data-lake-id="u552672cd" id="u552672cd"><br></p>
  <p data-lake-id="u005ea8ee" id="u005ea8ee"><br></p>
 </body>
</html>